use std::env;
use ctor::{ctor, dtor};
use dotenv::dotenv;
use time::macros::{format_description, offset};
use tracing::{error, info, Level};
use tracing_subscriber::fmt::time::OffsetTime;

use crate::constants::{ENV_LOGGER_LEVEL_KEY, ENV_PROFILES_ACTIVE_KEY};

/// 在这里初始化资源，程序启动时调用，在main()之前调用
///
/// 初始化顺序按初始化定义函数先后顺序
///

#[ctor]
fn init_check_env() {
    dotenv().ok();

    // 逐个获取环境变量的值
    if let Err(_) = env::var(ENV_PROFILES_ACTIVE_KEY.as_str()) {
        println!("未设置环境变量: {}", ENV_PROFILES_ACTIVE_KEY.as_str());
        std::process::exit(0);
    }
    if let Err(_) = env::var(ENV_LOGGER_LEVEL_KEY.as_str()) {
        println!("未设置环境变量: {}", ENV_LOGGER_LEVEL_KEY.as_str());
        std::process::exit(0);
    }
}

#[ctor]
fn init_logger() {
    // 从环境变量中读取日志级别配置
    let log_level = env::var(ENV_LOGGER_LEVEL_KEY.as_str()).unwrap_or("info".to_string()).to_uppercase();
    let log_level = match log_level.as_str() {
        "TRACE" => Level::TRACE,
        "DEBUG" => Level::DEBUG,
        "INFO" => Level::INFO,
        "WARN" => Level::WARN,
        "ERROR" => Level::ERROR,
        _ => {
            Level::INFO
        }
    };

    let time_fmt =
        format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]");
    let timer = OffsetTime::new(offset!(+8), time_fmt);

 /*   let appender = tracing_appender::rolling::daily("logs", "server.log");
    let stdout = std::io::stdout.with_max_level(log_level);*/

    /*tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .with_timer(timer)
        // .with_timer(LocalTimer)
        .with_writer(stdout.and(appender))
        .with_line_number(true)
        .with_thread_ids(true)
        .init();*/

    tracing_subscriber::fmt()
        // filter spans/events with level TRACE or higher.
        .with_max_level(log_level)
        .with_timer(timer)
        .with_line_number(true)
        // build but do not install the subscriber.
        .init();

    info!(">>>>初始化日志系统，日志级别: {}", log_level);
}

// 在main()之后调用
#[dtor]
fn shut_down() {
    error!("程序终止，并退出！");
}
